package lime2;

import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import lights.interfaces.ITuple;

public abstract class ABaseRRMgr implements IRRMgr {

	/*
	 * hashtable of strong reactions: it is managed by the LimeTSMgr, but since
	 * Reactor automatically removes strong once reactions after firing, Reactor
	 * needs to update it too. Because we can use JDK5 or higher now, we can
	 * utilize type-safe generic.
	 */
	Map<ReactionID, RegisteredReaction> registry;

	public ABaseRRMgr() {
		super();
	}

	public ABaseRRMgr(Hashtable<ReactionID, RegisteredReaction> reg) {
		registry = reg;

		Set<Map.Entry<ReactionID, RegisteredReaction>> s = reg.entrySet();
		for (Iterator iterator = s.iterator(); iterator.hasNext();) {
			Map.Entry<ReactionID, RegisteredReaction> entry = (Map.Entry<ReactionID, RegisteredReaction>) iterator
					.next();
			putReaction(entry.getValue());
		}
	}

	@Override
	public final boolean containsKey(ReactionID id) {
		return registry.containsKey(id);
	}

	@Override
	public final void put(RegisteredReaction newReaction) {
		registry.put(newReaction.getReactionID(), newReaction);
		putReaction(newReaction);
	}

	@Override
	public final boolean[] remove(ReactionID[] rids) {
		boolean[] ret = new boolean[rids.length];

		for (int i = 0; i < rids.length; i++) {
			RegisteredReaction found = registry.remove(rids[i]);

			if (found == null)
				ret[i] = false;
			else {
				ret[i] = true;
				remove(found);
			}
		}

		return ret;
	}

	abstract protected void remove(RegisteredReaction founds);

	abstract protected void putReaction(RegisteredReaction rr);

	static void findMatchTemplate(Map<ReactionID, RegisteredReaction> map,
			ITuple newTuple, List<RegisteredReaction> ret) {
		Set<Map.Entry<ReactionID, RegisteredReaction>> s = map.entrySet();
		Map.Entry<ReactionID, RegisteredReaction> entry = null;
		for (Iterator iterator = s.iterator(); iterator.hasNext();) {
			entry = (Map.Entry<ReactionID, RegisteredReaction>) iterator.next();
			if (TupleSpaceProxy.matchTuples(entry.getValue().getTemplate(),
					newTuple)) {
				ret.add(entry.getValue());
			}
		}
	}

}